package vn.conghuy.talkwithme.responsor.responsor;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import vn.conghuy.talkwithme.R;
import vn.conghuy.talkwithme.data.sqlmodel.SqlData;
import vn.conghuy.talkwithme.responsor.action.CalendarAction;
import vn.conghuy.talkwithme.utils.DateWrapper;
import vn.conghuy.talkwithme.utils.IntWrapper;
import vn.conghuy.talkwithme.utils.Parser;
import vn.conghuy.talkwithme.utils.StringWrapper;
import vn.conghuy.talkwithme.utils.Utils;
import android.content.Context;
import android.util.Log;

public class CalendarResponsor extends Responsor {
	
	private static final String REMIND_KEYWORD = "remind";
	private static final String CREATE_KEYWORD = "create";
	private static final String APPOINTMENT_KEYWORD = "appointment";
	private static final String ME_KEYWORD = "me";
	private static final String TO_KEYWORD = "to";
	private static final String CONTENT_KEYWORD = "content";
	private static final String IN_KEYWORD = "in";
	private static final String SCHEDULE_KEYWORD = "schedule";
	
	private static final int PARSE_REQUEST_OK = 0;
	private static final int PARSE_REQUEST_FAIL = 1;
	private static final int PARSE_REQUEST_MISS_DATE = 2;
	private static final int PARSE_REQUEST_MISS_CONTENT = 3;
	private static final int PARSE_REQUEST_MISS_ALL = 4;
	
	private static final int RELATIVE_MISS_INFO = 1;
	
	int parseResult;
	int oldParseResult;
	Date date;
	String content;
	
	public CalendarResponsor(Context context) {
		super(context);
		this.context = context;
	}
	
	
	@Override
	public String response(String request) {
		oldParseResult = parseResult;
		if(Utils.isExistStringInArray(SqlData.stopWords, request) == true){
			relativeLastResponse = RELATIVE_NONE;
			return Utils.getRandomString(SqlData.taskStop);
		}
		
		switch (relativeLastResponse) {
		case RELATIVE_NONE:
			parseResult = parseRequest(request);
			switch (parseResult) {
			case PARSE_REQUEST_OK:
				CalendarAction cal = new CalendarAction(context);
				cal.createAppointment(content, date);
				relativeLastResponse = RELATIVE_NONE;
				return context.getString(R.string.create_appointment_command);
				
			case PARSE_REQUEST_MISS_DATE:
				relativeLastResponse = RELATIVE_MISS_INFO;
				return Utils.getRandomString(SqlData.calendarMissDate);
			case PARSE_REQUEST_MISS_CONTENT:
				relativeLastResponse = RELATIVE_MISS_INFO;
				return Utils.getRandomString(SqlData.calendarMissContent);
			case PARSE_REQUEST_MISS_ALL:
				relativeLastResponse = RELATIVE_MISS_INFO;
				return Utils.getRandomString(SqlData.calendarMissAll);
			case PARSE_REQUEST_FAIL:
				return null;
				
			default:
				break;
			}
			break;
		case RELATIVE_MISS_INFO:
			parseResult = parseRequestInMissInfoCase(request);
			switch (parseResult) {
			case PARSE_REQUEST_OK:
				CalendarAction cal = new CalendarAction(context);
				cal.createAppointment(content, date);
				relativeLastResponse = RELATIVE_NONE;
				return context.getString(R.string.create_appointment_command);
				
			case PARSE_REQUEST_MISS_CONTENT:
				relativeLastResponse = RELATIVE_MISS_INFO;
				return Utils.getRandomString(SqlData.calendarMissContent);
				
			case PARSE_REQUEST_MISS_DATE:
				//check maybe user miss date twice (because input wrong format of date phrase)
				if(oldParseResult == PARSE_REQUEST_MISS_DATE && parseResult == PARSE_REQUEST_MISS_DATE){
					relativeLastResponse = RELATIVE_MISS_INFO;
					return Utils.getRandomString(SqlData.calendarMissDateAgain);
				}
				else{
					relativeLastResponse = RELATIVE_MISS_INFO;
					return Utils.getRandomString(SqlData.calendarMissDate);
				}
			default:
				break;
			}
		default:
			break;
		}
		
		return super.response(request);
	}

	@Override
	public int relativeWithLastRequest(String sentence) {
		return relativeLastResponse;
	}

	int parseRequest(String request){
		StringWrapper verbWrapper = new StringWrapper();
		
		if(isCalendarRequest(request, verbWrapper)){
			String verb = verbWrapper.getStr();
			String datePhrase = null;
			int contentIndex = -1;
			int dateIndex = -1;
			
			// get content index
			if(verb.equals(REMIND_KEYWORD)){			//example : remind me to "meet Gerrard" at  August 25 2012
				contentIndex = Utils.indexOfWord(request, TO_KEYWORD);	
				if(contentIndex == -1){
					contentIndex = Utils.indexOfWord(request, ME_KEYWORD);	
					if(contentIndex == -1){
						contentIndex = Utils.indexOfWord(request, REMIND_KEYWORD);	
						contentIndex += REMIND_KEYWORD.length() + 1;
					}
					else contentIndex += ME_KEYWORD.length() + 1;
				}
				else contentIndex += TO_KEYWORD.length() + 1;
			}
			else if(verb.equals(CREATE_KEYWORD)){		//example : create an appointment with content "meet Gerrard" at  August 25 2012
				contentIndex = Utils.indexOfWord(request, CONTENT_KEYWORD);	
				if(contentIndex == -1){
					contentIndex = Utils.indexOfWord(request, APPOINTMENT_KEYWORD);	
					contentIndex += APPOINTMENT_KEYWORD.length() + 1;
				}
				else contentIndex += CONTENT_KEYWORD.length() + 1;
			}
			else if(verb.equals(SCHEDULE_KEYWORD)){
				contentIndex = Utils.indexOfWord(request, SCHEDULE_KEYWORD);	
				contentIndex += SCHEDULE_KEYWORD.length() + 1;
			}
			
			
			// get to index
			dateIndex = Utils.lastIndexOfWord(request, IN_KEYWORD);
			
			//parse
			if(dateIndex == -1){
				if(contentIndex < request.length() - 1){
					content = request.substring(contentIndex);
					return PARSE_REQUEST_MISS_DATE;
				}
				else{
					return PARSE_REQUEST_MISS_ALL;
				}
			}
			else{
				dateIndex += TO_KEYWORD.length() + 1;
				datePhrase = request.substring(dateIndex);
				boolean parseDateResult = parseDate(datePhrase);
				
				if(parseDateResult == true){
					if(contentIndex < dateIndex - IN_KEYWORD.length() - 2){			//2 is two blank spaces
						content = request.substring(contentIndex, dateIndex - IN_KEYWORD.length() - 2);
						return PARSE_REQUEST_OK;
					}
					else{
						return PARSE_REQUEST_MISS_CONTENT;
					}
				}
				else{
					content = request.substring(contentIndex);
					return PARSE_REQUEST_MISS_DATE;
				}
			}
		}
		return PARSE_REQUEST_FAIL;
	}
	
	int parseRequestInMissInfoCase(String request){
		switch (parseResult) {
		case PARSE_REQUEST_MISS_ALL:
			String datePhrase = "";
			boolean parseDateResult;
			int dateIndex = Utils.lastIndexOfWord(request, IN_KEYWORD);
			if(dateIndex == -1){											// if request hasn't "in" keyword
				parseDateResult = parseDate(datePhrase);					// try parse date
				if(parseDateResult == true){								// if parse success
					return PARSE_REQUEST_MISS_CONTENT;
				}
				else{														// else if parse fail
					content = request;										// all request is content
					return PARSE_REQUEST_MISS_DATE;
				}
			}
			else{															// else if has "in" keyword
				dateIndex += TO_KEYWORD.length() + 1;
				datePhrase = request.substring(dateIndex);
				parseDateResult = parseDate(datePhrase);					// try parse date
				
				if(parseDateResult == true){								// if parse date success
					if(dateIndex - IN_KEYWORD.length() - 2 > 0){			// and has content before "in" keyword, assign keyword
						content = request.substring(0, dateIndex - IN_KEYWORD.length() - 2);	//2 is two blank spaces
						return PARSE_REQUEST_OK;
					}
					else{
						return PARSE_REQUEST_MISS_CONTENT;
					}
				}
				else{														// if parse date fail
					content = request;										// assign content by request
					return PARSE_REQUEST_MISS_DATE;
				}
			}
			
		case PARSE_REQUEST_MISS_CONTENT:
			content = request;
			return PARSE_REQUEST_OK;
			
		case PARSE_REQUEST_MISS_DATE:
			dateIndex = Utils.lastIndexOfWord(request, IN_KEYWORD);
			if(dateIndex != -1){
				dateIndex += IN_KEYWORD.length() + 1;
				datePhrase = request.substring(dateIndex);
			}
			else{
				datePhrase = request;
			}
			parseDateResult = parseDate(datePhrase);
			if(parseDateResult == true){
				return PARSE_REQUEST_OK;
			}
			else{
				return PARSE_REQUEST_MISS_DATE;
			}

		default:
			break;
		}
		return PARSE_REQUEST_FAIL;
	}
	
	boolean parseDate(String datePhrase){
		DateWrapper dateWrapper = new DateWrapper();
		boolean result = Parser.parseDate(datePhrase, dateWrapper);
		date = dateWrapper.getDate();
		return result;
	}
	
	boolean isCalendarRequest(String request, StringWrapper outVerb){
		if(request.contains(REMIND_KEYWORD)){
			outVerb.setStr(REMIND_KEYWORD);
			return true;
		}
		else if(request.contains(CREATE_KEYWORD) && request.contains(APPOINTMENT_KEYWORD)){
			outVerb.setStr(CREATE_KEYWORD);
			return true;
		}
		else if(request.contains(SCHEDULE_KEYWORD)){
			outVerb.setStr(SCHEDULE_KEYWORD);
			return true;
		}
		return false;
	}
	
	@Override
	public int indexOfMainVerb(String request) {
		StringWrapper verbWrapper = new StringWrapper();
		if(isCalendarRequest(request, verbWrapper))
			return Utils.indexOfWord(request, verbWrapper.getStr());
		else return -1;
	}
}
